from Cube.gui.DirectGUIPropertiesAccess import HeightGet as FrameHeightGet
from Cube.gui.DirectGUIPropertiesAccess import WidthGet as FrameWidthGet
from Cube.gui.DirectGUIPropertiesAccess import ScaleGet as FrameScaleGet
from Cube.gui.Utility import WinXYGet

class QSizer():
    # flag at Add()
    EXPAND = 0
    ALIGN_CENTER = 1
    ALIGN_LEFT = 2
    ALIGN_RIGHT = 4
    ALIGN_TOP = 8
    ALIGN_BOTTOM = 16

    def __init__(self, **kw):
        if kw.has_key("size"):
            self.size = kw["size"]
            self.pos = kw.get("pos", (0,0,0))
        else:
            self.pos = None       # (X,Y,Z)
            self.size = None      # (Left,Right,Bottom,Top)
        self.scale = (1,1,1)  # interface compatibility for DirectGUI

        self.SlotList = []

    def __setitem__(self, key, value):
        # interface compatibility for DirectGUI
        if key == "frameSize": self.size = value
        else: print "QSize does not implement this access"

    def setPos(self,x,y,z):
        # interface compatibility for DirectGUI
        self.pos = (x,y,z)

    def __getitem__(self, key):
        # interface compatibility for DirectGUI
        if key == "pos": ret = self.pos
        elif key == "frameSize": ret = self.size
        elif key == "scale": ret = self.scale
        else:
            print "QSize does not implement this access"
            ret = None
        return ret

    def Add(self, guiObject, proportion = 1, flag = 0):
        itemDict = dict( guiObject = guiObject,
                         proportion = proportion,
                         flag = flag )
        self.SlotList.append(itemDict)

    def Attach2Frame(self, frame = None):
        if frame: frame._getSizer = self
        else:
            # attach QSize to win
            scaleX, scaleY = WinXYGet()
            self.pos = (0,0,0)
            self.size = ((-1)*scaleX, scaleX,(-1)*scaleY, scaleY)

    def BoundaryGet(self):
        posX, posY, posZ = self.pos
        size_left, size_right, size_bottom, size_top = self.size
        LeftX = posX + size_left
        RightX = posX + size_right
        BottomZ = posZ + size_bottom
        TopZ = posZ + size_top
        return (LeftX,RightX,BottomZ,TopZ)

    # override it in child Sizer klass
    def Layout(self):
        pass

    # override it in child Sizer klass
    def SizerHightGet(self):
        pass

    # override it in child Sizer klass
    def SizerWidthGet(self):
        pass


def QSizerGet(obj):
    if isinstance(obj, QSizer):
        sizer = obj
    elif hasattr(obj,"_getSizer"):
        sizer = obj._getSizer
    else: sizer = None
    return sizer

def ObjectHeightGet(obj):
    sizer = QSizerGet(obj)
    if sizer:
        ret = sizer.SizerHightGet()
        # remember to overrider this method
    else:
        ret = FrameHeightGet(obj)
    return ret

def ObjectWidthGet(obj):
    sizer = QSizerGet(obj)
    if sizer:
        ret = sizer.SizerWidthGet()
        # remember to overrider this method
    else:
        ret = FrameWidthGet(obj)
        #print obj,ret
    return ret

def ObjectPosSizeSet(guiObject, sizerBoundXZ, flagXZ):
    # get attached sizer
    sizer = QSizerGet(guiObject)
    if sizer: guiObject = sizer

    sizerLeftBound, sizerRightBound, sizerTopBound, sizerBottomBound = sizerBoundXZ
    flagX, flagZ = flagXZ
    scaleX, scaleY, scaleZ = FrameScaleGet(guiObject)

    centerPointX = (sizerLeftBound+sizerRightBound)*0.5
    centerPointZ = (sizerTopBound+sizerBottomBound)*0.5
    half_sizerWidth = centerPointX - sizerLeftBound
    half_sizerHeight = centerPointZ - sizerBottomBound

    if flagX == QSizer.EXPAND:
        objPointX = centerPointX
        objLeftBound, objRightBound = -1*half_sizerWidth, half_sizerWidth
    else:
        half_ObjectWidth = ObjectWidthGet(guiObject)*0.5
        if (flagX & QSizer.ALIGN_LEFT):
            objPointX = sizerLeftBound + half_ObjectWidth
        elif (flagX & QSizer.ALIGN_RIGHT):
            objPointX = sizerRightBound - half_ObjectWidth
        else:
            objPointX = centerPointX
        objLeftBound, objRightBound = -1*half_ObjectWidth, half_ObjectWidth

    if flagZ == QSizer.EXPAND:
        objPointZ = centerPointZ
        objTopBound, objBottomBound = -1*half_sizerHeight, half_sizerHeight
    else:
        half_ObjectHeight = ObjectHeightGet(guiObject)*0.5
        if (flagZ & QSizer.ALIGN_TOP):
            objPointZ = sizerTopBound - half_ObjectHeight
        elif (flagZ & QSizer.ALIGN_BOTTOM):
            objPointZ = sizerBottomBound + half_ObjectHeight
        else:
            objPointZ = centerPointX
        objTopBound, objBottomBound = -1*half_ObjectHeight, half_ObjectHeight

    # now we have got objPointX, objPointZ,
    #                 objLeftBound, objRightBound, objBottomBound, objTopBound
    guiObject.setPos(objPointX, 0, objPointZ)
    guiObject["frameSize"] = (objLeftBound/scaleX, objRightBound/scaleX,
                                  objBottomBound/scaleZ, objTopBound/scaleZ)
    # do resized call back
    if hasattr(guiObject,"_QSizerResizedCallBack"):
        guiObject._QSizerResizedCallBack(*guiObject._QSizerResizedCallBackArgv,
                                         **guiObject._QSizerResizedCallBackArgs)

    #print "resize:",guiObject


def ResizedCallBackSet(guiObject, handle, *argv, **args):
    guiObject._QSizerResizedCallBack = handle
    guiObject._QSizerResizedCallBackArgv = argv
    guiObject._QSizerResizedCallBackArgs = args

